<template>
	<pd-popup ref="popup" @change="popupChangeHandler">
		<view class="__pd_date_range_picker">
			<slot></slot>
			<view class="__picker_area">
				<picker-view :value="result" @pickstart='pickerInScrolling = true' @pickend='pickerInScrolling = false'
					@change="pickerChangeHandler" v-if="result.length">
					<picker-view-column class="__picker_view">
						<view class="__picker_item" :class="{ '__picker_active': index === result[0] }"
							v-for="(item, index) in pickerOps[0]" :key="index">{{ item }}</view>
					</picker-view-column>
					<picker-view-column class="__picker_view">
						<view class="__picker_item" :class="{ '__picker_active': index === result[1] }"
							v-for="(item, index) in pickerOps[1]" :key="index">{{ item }}</view>
					</picker-view-column>
					<picker-view-column class="__picker_view">
						<view class="__picker_item" :class="{ '__picker_active': index === result[2] }"
							v-for="(item, index) in pickerOps[2]" :key="index">{{ item }}</view>
					</picker-view-column>
				</picker-view>
			</view>
			<view class="__picker_footer">
				<button type="default" @tap="cancelHandler">取消</button>
				<button type="primary" :disabled="pickerInScrolling" @tap="confirmHandler">确认</button>
			</view>
		</view>
	</pd-popup>
</template>

<script setup lang="ts">
import PdPopup from './pd-popup.vue';
import { useCompRef } from '@/pd-libs/hooks/useRefs';
import PD from '../libs';
import type { WxFormChangeRes } from '../libs/wx-types';
import type { TsHelp } from '../libs/ts-help';
const result = ref<number[]>([]);//所选下标
const pickerOps = ref<Array<number[]>>([]);//选项数据
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
const day = now.getDate();

let startTimestamp = 0;//开始时间限制
let endTimestamp = 0;//结束时间限制

const popup = useCompRef(PdPopup);
const pickerInScrolling = ref(false);

let resolver: TsHelp.PromiseResolver<{ value: number }>;
let rejecter: () => void;
type Ops = {
	startTimestamp?: number,//起始时间戳，如果有传入，则会根据这个时间开始生成日期
	endTimestamp ?: number,
};
const open = (ops?: Ops): Promise<{ value: number }> => {
	return new Promise((r, j) => {
		(ops && ops.startTimestamp) && (startTimestamp = ops.startTimestamp);
		(ops && ops.endTimestamp) && (endTimestamp = ops.endTimestamp);
		resolver = r;
		rejecter = j;
		initOps();
		initResult();
		popup.value?.open();
	});
};

const pickerChangeHandler = (e: WxFormChangeRes<number[]>) => {
	//尝试重新生成月份数据
	if (e.detail.value[0] === 0 && startTimestamp) {
		pickerOps.value[1] = PD.Tool.createArray(new Date(startTimestamp).getMonth() + 1, 12);
	} else if (e.detail.value[0] === pickerOps.value[0].length - 1 && endTimestamp) {
		pickerOps.value[1] = PD.Tool.createArray(1, new Date(endTimestamp).getMonth() + 1);
	} else {
		pickerOps.value[1] = PD.Tool.createArray(1,12);
	};

	//尝试重新生成日期数据
	if (startTimestamp) {
		pickerOps.value[2] = PD.Tool.createArray(
			e.detail.value[0] === 0 && e.detail.value[1] === 0 ? new Date(startTimestamp).getDate() : 1,
			new Date(pickerOps.value[0][e.detail.value[0]], pickerOps.value[1][e.detail.value[1]], 0).getDate()
		);
	} else if (endTimestamp) {
		pickerOps.value[2] = PD.Tool.createArray(
			1,
			e.detail.value[0] === pickerOps.value[0].length - 1 && e.detail.value[1] === pickerOps.value[1].length - 1 ? new Date(endTimestamp).getDate() : new Date(pickerOps.value[0][e.detail.value[0]], pickerOps.value[1][e.detail.value[1]], 0).getDate()
		);
	} else {
		pickerOps.value[2] = PD.Tool.createArray(
			1,
			new Date(pickerOps.value[0][e.detail.value[0]], pickerOps.value[1][e.detail.value[1]], 0).getDate()
		);
	};
	
	result.value = e.detail.value;
};

const initOps = () => {
	if (!startTimestamp && !endTimestamp) {
		pickerOps.value = [
			PD.Tool.createArray(year - 5, year + 5),
			PD.Tool.createArray(1, 12),
			PD.Tool.createArray(
				1,
				new Date(year, month, 0).getDate()
			),
		];
		return;
	};
	const v = new Date(startTimestamp || endTimestamp);
	const vyear = v.getFullYear();
	const vmonth = v.getMonth() + 1;
	pickerOps.value = [
		startTimestamp ? PD.Tool.createArray(vyear, vyear + 50) : PD.Tool.createArray(vyear - 50, vyear),
		startTimestamp ? PD.Tool.createArray(vmonth, 12) : PD.Tool.createArray(1, vmonth),
		PD.Tool.createArray(
			startTimestamp ? v.getDate() : 1,
			startTimestamp ? new Date(vyear, vmonth, 0).getDate() : v.getDate()
		),
	];
};

const initResult = () => {
	result.value = [
		pickerOps.value[0].indexOf(startTimestamp || endTimestamp ? new Date(startTimestamp || endTimestamp).getFullYear() : year),
		pickerOps.value[1].indexOf(startTimestamp || endTimestamp ? new Date(startTimestamp || endTimestamp).getMonth() + 1 : month),
		pickerOps.value[2].indexOf(startTimestamp || endTimestamp ? new Date(startTimestamp || endTimestamp).getDate() : day),
	];
};

const confirmHandler = () => {
	resolver && resolver({
		value: new Date(pickerOps.value[0][result.value[0]], pickerOps.value[1][result.value[1]] - 1, pickerOps.value[2][result.value[2]]).getTime()
	});
	popup.value?.close();
};

const cancelHandler = () => {
	rejecter && rejecter();
	popup.value?.close();
};

const popupChangeHandler = (show: boolean) => {
	!show && cancelHandler();
};

defineExpose({
	open,
});

</script>

<style scoped lang="less">
.__pd_date_range_picker {
	padding: 32rpx 24rpx;
	background: #fff;
	border-radius: 16rpx 16rpx 0 0;

	.__picker_area {
		font-size: 28rpx;
		--h: 350rpx;

		.__picker_view {
			height: var(--h);
		}

		.__picker_item {
			display: flex;
			align-items: center;
			justify-content: center;
		}

		.__picker_active {
			font-size: 32rpx;
			font-weight: bold;
			color: var(--primary);
		}

		.__buffer_tag {
			width: 50rpx;
			text-align: center;
			height: var(--h);
			line-height: var(--h);
		}
	}

	.__picker_footer {
		margin-top: 50rpx;
		display: flex;
		gap: 32rpx;

		button {
			flex: 1;
		}
	}
}
</style>